#ifndef COMMONDEFINE_H
#define COMMONDEFINE_H

#include <QVector>

#define XML_ROOT "OpenDRIVE"
#define XML_HEADER "header"
#define XML_DATE "date"
#define XML_NAME "name"
#define XML_EAST "east"
#define XML_NORTH "north"
#define XML_SOUTH "south"
#define XML_WEST "west"
#define XML_REVMAJOR "revMajor"
#define XML_REVMINOR "revMinor"
#define XML_VENDOR "vendor"
#define XML_VERSION "version"
#define XML_GEO "geoReference"
#define XML_ROAD "road"
#define XML_ID "id"
#define XML_JUNCTION "junction"
#define XML_LENGTH "length"
#define XML_LINK "link"
#define XML_PREDECESSOR "predecessor"
#define XML_SUCCESSOR "successor"
#define XML_CONTACTPOINT "contactPoint"
#define XML_ELEMENTID "elementId"
#define XML_ELEMENTTYPE "elementType"
#define XML_TYPE "type"
#define XML_S "s"
#define XML_PLANVIEW "planView"
#define XML_GEOMETRY "geometry"
#define XML_HDG "hdg"
#define XML_X "x"
#define XML_Y "y"
#define XML_LINE "line"
#define XML_ARC "arc"
#define XML_SPIRAL "spiral"
#define XML_POLY3 "poly3"
#define XML_CURVATURE "curvature"
#define XML_CURVSTART "curvStart"
#define XML_CURVEND "curvEnd"
#define XML_A "a"
#define XML_B "b"
#define XML_C "c"
#define XML_D "d"
#define XML_ELEVATIONPROFILE "elevationProfile"
#define XML_ELEVATION "elevation"
#define XML_LANES "lanes"
#define XML_LANEOFFSET "laneOffset"
#define XML_LANESECTION "laneSection"
#define XML_LEFT "left"
#define XML_CENTER "center"
#define XML_RIGHT "right"
#define XML_LANE "lane"
#define XML_LEVEL "level"
#define XML_WIDTH "width"
#define XML_SOFFSET "sOffset"
#define XML_ROADMARK "roadMark"
#define XML_COLOR "color"
#define XML_WEIGHT "weight"
#define XML_SPEED "speed"
#define XML_MAX "max"
#define XML_HEIGHT "height"
#define XML_INNER "inner"
#define XML_OUTER "outer"
#define XML_USERDATA "userData"
#define XML_CODE "code"
#define XML_STYLE "style"
#define XML_LANESTYLE "laneStyle"
#define XML_MAPPING "mapping"
#define XML_FILLET "fillet"
#define XML_POS "pos"
#define XML_OBJECTS "objects"
#define XML_OBJECT "object"
#define XML_T "t"
#define XML_ZOFFSET "zOffset"
#define XML_PITCH "pitch"
#define XML_ROLL "roll"
#define XML_REPEAT "repeat"
#define XML_DISTANCE "distance"
#define XML_TSTART "tStart"
#define XML_TEND "tEnd"
#define XML_WIDTHSTART "widthStart"
#define XML_WIDTHEND "widthEnd"
#define XML_HEIGHTSTART "heightStart"
#define XML_HEIGHTEND "heightEnd"
#define XML_ZOFFSETSTART "zOffsetStart"
#define XML_ZOFFSETEND "zOffsetEnd"
#define XML_SIGNALS "signals"
#define XML_SIGNAL "signal"
#define XML_DYNAMIC "dynamic"
#define XML_ORIENTATION "orientation"
#define XML_COUNTRY "country"
#define XML_SUBTYPE "subtype"
#define XML_HOFFSET "hOffset"
#define XML_VALUE "value"
#define XML_CONTROLLER "controller"
#define XML_CONTROL "control"
#define XML_SIGNALID "signalId"
#define XML_JUNCTION "junction"
#define XML_CONNECTION "connection"
#define XML_INCOMINGROAD "incomingRoad"
#define XML_CONNECTINGROAD "connectingRoad"
#define XML_LANELINK "laneLink"
#define XML_FROM "from"
#define XML_TO "to"
#define XML_BROKEN "broken"

// 旧版本lane > height属性对应新版本inner和outer
#define XML_HEIGHTINNER "heightInner"
#define XML_HEIGHTOUTER "heightOuter"
// 本文件中结构体命名前带S的均为和lane.h中结构体做区分

struct Header
{
    std::string date;
    std::string name;
    double east = 0.0;
    double north = 0.0;
    double south = 0.0;
    double west = 0.0;
    std::string revMajor;
    std::string revMinor;
    std::string vendor;
    std::string version;
    std::string geoReference;
};

struct LinkParameter
{
    std::string contactPoint;
    std::string elementId;
    std::string elementType;
};

struct RoadLink
{
    LinkParameter predecessor;
    LinkParameter successor;
};

struct RoadType
{
    std::string s;
    std::string type;
};

struct SCoefficients
{
    double a = 0.0;
    double b = 0.0;
    double c = 0.0;
    double d = 0.0;
};

struct SGeometry
{
    double hdg = 0.0;
    double length = 0.0;
    double s = 0.0;
    double x = 0.0;
    double y = 0.0;
    std::string type;
    SCoefficients extend;
};

struct PlanView
{
    QVector<SGeometry> qvecGeometry;
};

struct SElevation
{
    double s = 0.0;
    SCoefficients coefficients;
};

struct ElevationProfile
{
    QVector<SElevation> qvecElevation;
};

struct SLaneOffset
{
    double s = 0.0;
    SCoefficients coefficients;
};

struct Width
{
    SCoefficients coefficients;
    std::string sOffset;
    bool bExist = false;
};

struct RoadMark
{
    std::string color;
    std::string sOffset;
    std::string type;
    std::string weight;
    bool bExist = false;
};

struct Speed
{
    std::string sOffset;
    std::string max;
    bool bExist = false;
};

struct Height
{
    std::string sOffset;
    std::string inner;
    std::string outer;
    bool bExist = false;
};

struct Style
{
    std::string sOffset;
    std::string laneStyle;
    std::string mapping;
    bool bExist = false;
};

struct Fillet
{
    std::string pos;
    std::string style;
    std::string id;
    bool bExist = false;
};

struct UserData
{
    std::string code;
    Style style;
    Fillet fillet;
    bool bExist = false;
};

struct LaneLinkParameter
{
    std::string id;
    bool bExist = false;
};

struct LaneLink
{
    LaneLinkParameter predecessor;
    LaneLinkParameter successor;
    bool bExist = false;
};

struct SLane
{
    std::string id;
    std::string level;
    std::string type;
    LaneLink link;
    Width width;
    RoadMark roadMark;
    Speed speed;
    Height height;
    UserData userData;
};

struct Layout
{
    QVector<SLane> qvecLane;
    bool bExist = false;
};

struct SLaneSection
{
    double s = 0.0;
    Layout left;
    Layout center;
    Layout right;
};

struct Lanes
{
    QVector<SLaneOffset> qvecLaneOffset;
    QVector<SLaneSection> qvecLaneSection;
};

struct Repeat
{
    double s = 0.0;
    double length = 0.0;
    double distance = 0.0;
    double tStart = 0.0;
    double tEnd = 0.0;
    double widthStart = 0.0;
    double widthEnd = 0.0;
    double heightStart = 0.0;
    double heightEnd = 0.0;
    double zOffsetStart = 0.0;
    double zOffsetEnd = 0.0;
    bool bExist = false;
};

struct Object
{
    std::string id;
    std::string type;
    std::string name;
    double s = 0.0;
    double t = 0.0;
    double zOffset = 0.0;
    double length = 0.0;
    double width = 0.0;
    double height = 0.0;
    double hdg = 0.0;
    double pitch = 0.0;
    double roll = 0.0;
    Repeat repeat;
};

struct Objects
{
    QVector<Object> qvecObject;
};

struct SignalUserData
{
    std::string code;
    double value = 0.0;
    bool bExist = false;
};

struct Signal
{
    double s = 0.0;
    double t = 0.0;
    std::string id;
    std::string name;
    std::string dynamic;
    std::string orientation;
    double zOffset = 0.0;
    std::string type;
    std::string country;
    std::string subtype;
    double value = 0.0;
    double unit = 0.0;
    double hOffset = 0.0;
    double pitch = 0.0;
    double roll = 0.0;
    double height = 0.0;
    double width = 0.0;
    SignalUserData userData;
};

struct Signals
{
    QVector<Signal> qvecSignal;
};

struct SRoad
{
    std::string id;
    std::string name;
    std::string junction;
    double length = 0.0;
    RoadLink roadLink;
    RoadType roadType;
    PlanView planView;
    ElevationProfile elevationProfile;
    Lanes lanes;
    Objects objects;
    Signals roadSignals;
};

struct Control
{
    std::string signalId;
    std::string type;
};

struct SController
{
    std::string id;
    QVector<Control>  qvecControl;
};

struct ConnectLaneLink
{
    std::string from;
    std::string to;
};

struct Connection
{
    std::string id;
    std::string incomingRoad;
    std::string connectingRoad;
    std::string contactPoint;
    QVector<ConnectLaneLink> qvecLaneLink;
};

struct JunctionController
{
    std::string id;
};

struct Junction
{
    std::string id;
    std::string name;
    QVector<Connection> qvecConnection;
    QVector<JunctionController> qvecController;
};

#endif // COMMONDEFINE_H
